/*
 * Created by kopper on 01.02.15 08:42
 * (C) Copyright 2015 kopperek@gmail.com
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 */

package app.android.kopper.gpxdownloader.parser;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

import app.android.kopper.gpxdownloader.IUtilProvider;
import app.android.kopper.gpxdownloader.LogProxy;
import app.android.kopper.gpxdownloader.R;

public abstract class AbstractParser {

	
	private static final SimpleDateFormat GPX_DATE_FORMAT=new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    private final File file;
    protected final long fileSize;


    class PointDef {
		private Date date;
		private float lat;
		private float lon;

		public PointDef(Date date,float lat, float lon) {
			this.date=date;
			this.lat=lat;
			this.lon=lon;
		}

		@Override
		public String toString() {
			return "PointDef [date=" + date + ", lat=" + lat + ", lon=" + lon
					+ "]";
		}

		public Date getDate() {
			return date;
		}

		public float getLat() {
			return lat;
		}

		public float getLon() {
			return lon;
		}
	}
	

	long filePos=0;
	private FileInputStream fis;

	public AbstractParser(File file,long fileSize) {
		this.file=file;
        this.fileSize=fileSize;
	}
	
	public final void parse(IUtilProvider utils) throws IOException {
			fis=new FileInputStream(file);
			try {
				performParsing(utils);
			} catch (Exception e) {
				throw e;
			} finally {
				fis.close();
			}
		}

	protected abstract void performParsing(IUtilProvider utils) throws IOException, FileNotFoundException;


	protected byte[] loadArray(int len,IUtilProvider utils) throws IOException {
		byte[] array=new byte[len];
		int received = fis.read(array);
		if(received!=len)
			throw new IOException(utils.getString(R.string.error_no_more_data));
		filePos+=len;
		return(array);
	}

	protected void seekTo(long newPosition,IUtilProvider utils) throws IOException {
		if(filePos>newPosition)
			throw new IOException(String.format(utils.getString(R.string.error_back_to_the_future),filePos,newPosition));
		fis.skip(newPosition-filePos);
		filePos=newPosition;
	}

	protected long extractLong(byte[] array) {
		long result=0;
		for(int a=0;a<array.length;a++)
			result=(result<<8)+(array[array.length-a-1]&0xff);
		return(result);
	}
	
	protected int available() throws IOException {
		return fis.available();
	}
	
	protected PrintWriter createGpxWriter(String gpxFileName, IUtilProvider utils) throws IOException {
		File gpxFile = utils.createFile(gpxFileName+".gpx");
		LogProxy.i(String.format(utils.getString(R.string.log_start_writing),gpxFile.getAbsolutePath()));
        PrintWriter gpxWriter = new PrintWriter(gpxFile);
		gpxWriter.println("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>");
		gpxWriter.println("<gpx creator=\"gpx.downloader 1.0\">");
		gpxWriter.println("<trk>");
		gpxWriter.println("<name>" + gpxFileName + "</name>");
		gpxWriter.println("<trkseg>");
		return gpxWriter;
	}
	
	protected void closeGpxWriter(PrintWriter gpxWriter) {
		gpxWriter.println("</trkseg>");
		gpxWriter.println("</trk>");
		gpxWriter.println("</gpx>");
		gpxWriter.close();
	}

	protected String createGpxFileName(PointDef item) {
		return new SimpleDateFormat("yyyyMMdd-HHmmss").format(item.getDate());
	}
	
	protected void writeTrackPoint(PrintWriter gpxWriter, PointDef item) {
		gpxWriter.println("<trkpt lat=\"" + item.getLat() + "\" lon=\"" + item.getLon() + "\">");
		gpxWriter.println("<time>" + GPX_DATE_FORMAT.format(item.getDate()) + "</time>");
		gpxWriter.println("</trkpt>");
	}


}